package com.fingard.dsp.bank.directbank.spdb01;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.IBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.detail.RetAtsBatPayRecDetail;
import com.fingard.dsp.bank.reqrespobj.single.detail.ReqPayRecDetail;
import com.fingard.dsp.basicbankdata.ebank.EBankData;
import com.fingard.text.StringHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.util.Calendar;

public class SPDB01BatPayRec extends SPDB01Base implements IBatPayRec {
    @Override
    public RetAtsBatPayRec d_1988_BatPay(ReqBatPayRec p_req1988) throws Exception {
        return batPayRec(p_req1988);
    }

    @Override
    public RetAtsBatPayRec d_9188_BatPay(ReqBatPayRec p_req9188) throws Exception {
        return batPayRec(p_req9188);
    }

    @Override
    public RetAtsQryBatPayRec d_1998_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
        return qryBatPayRec(p_req1998);
    }

    @Override
    public RetAtsQryBatPayRec d_9198_QryBatPay(ReqQryBatPayRec p_req9198) throws Exception {
        return qryBatPayRec(p_req9198);
    }

    private RetAtsBatPayRec batPayRec(ReqBatPayRec p_req) throws Exception {
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_req.reqHeader);
        retAts.reqSeqID = p_req.reqBatchNO;

        SPDB01Header tmpBnkHeader = new SPDB01Header();
        tmpBnkHeader.transCode = "AQ52";
        String batchNo = p_req.reqBatchNO;

        XmlTextWriter xmlWriter = new XmlTextWriter();
        String transType = p_req.reqHeader.transType;
        //需要进行对账码拼接以及节点解析，采用XElement进行处理
        xmlWriter.autoFormat = false;
        XElement tmpXElement = new XElement("body", "");
        tmpXElement.addChild(new XElement("transMasterID", bankFront.protocolNo));//交易客户号
        tmpXElement.addChild(new XElement("projectNumber", bankFront.corpNo));//
        tmpXElement.addChild(new XElement("projectName", bankFront.operator));//项目名称Y
        String costItemCode = "";
        if ("1988".equals(transType)) {
            costItemCode = "batPay|" + p_req.ownAct;
        } else {
            costItemCode = "batRec|" + p_req.ownAct;
        }
        tmpXElement.addChild(new XElement("costItemCode", costItemCodeMap(costItemCode)));//费项编码Y
//        tmpXElement.addChild(new XElement("costItemCode",   "01000"));//费项编码Y
        String type = "1"; //1:代收     2:代付
        if ("1988".equals(transType)) {
            type = "2";
        }
        tmpXElement.addChild(new XElement("transType", type));//交易类型Y
        tmpXElement.addChild(new XElement("elecChequeNo", batchNo));//电子凭证号Y
        tmpXElement.addChild(new XElement("onlyChannelFlag", "0"));//是否指定唯一渠道N  0:不指定渠道；  1:指定渠道；
        tmpXElement.addChild(new XElement("thirdChannelID", ""));//第三渠道IDY/N
        tmpXElement.addChild(new XElement("totalNumber", p_req.totalNum));//总笔数Y
        tmpXElement.addChild(new XElement("totalAmount", p_req.totalAmt));//总金额Y
        tmpXElement.addChild(new XElement("note", p_req.useType));//摘要N
        tmpXElement.addChild(new XElement("purpose", p_req.useType));//用途或附言N
        tmpXElement.addChild(new XElement("note1", ""));//备用字段1N
        tmpXElement.addChild(new XElement("note2", ""));//备用字段2N
        tmpXElement.addChild(new XElement("note3", ""));//备用字段3N
        tmpXElement.addChild(new XElement("batchNo", getRandString(6)));//批次号Y
        XElement lists = new XElement("lists", "");
        tmpXElement.addChild(lists);
        int seqNo = 15;
        ReqPayRecDetail detail = null;
        String msf = "|";
        while (p_req.readRecord()) {
            detail = p_req.readedDetail;
            StringBuilder sb = new StringBuilder();
            String cardtype = "";
            //payeeType 收款人账户类型 0-对公账号  1-卡  8-活期存折
            if ("1".equals(detail.cardType)) {
                cardtype = "8";
            } else {
                cardtype = "1";
            }

            String cnapsCode = "";
            String cnapsName = "";
            String payBankNo = "";
            if ("0".equalsIgnoreCase(p_req.readedDetail.sameBnk)) {
                String oppBankCode = p_req.readedDetail.recBankCode;
                String oppBankName = p_req.readedDetail.recBankName;
                if ("9188".equalsIgnoreCase(p_req.reqHeader.transType)) {
                    oppBankCode = p_req.readedDetail.payBankCode;
                    oppBankName = p_req.readedDetail.payBankName;
                }
                String[] ebankCodeName = EBankData.mappingEBankCode(oppBankCode, oppBankName);
                if(ebankCodeName!=null && ebankCodeName[0].length()>0){
                    cnapsCode = ebankCodeName[0];//收款行行号
                    cnapsName = ebankCodeName[1];
                }else{
                    cnapsCode = detail.cnapsCode;//收款行行号
                    cnapsName = detail.cnapsName;
                }

                payBankNo = getBankConfig().getMapValueByKey("payBankNoMapping", p_req.ownAct);
                if (StringHelper.isNullOrEmpty(payBankNo)) {
                    retAts.respCode = "0";
                    retAts.respInfo = "支付行号为空,请检查SPDB01/config.xml配置节点中'payBankNoMapping'节点配置是否正确!";
                    retAts.transState = PaymentState.FAIL_Batch;
                    retAts.payInfoCode = FailCode.E9981;
                    retAts.writeRetToATS();
                    return retAts;
                }
            }

            XElement list = new XElement("list", "");
            String oppAct = detail.payAct;
            String oppActNm = detail.payName;
            if ("1988".equals(transType)) {
                oppAct = detail.recAct;
                oppActNm = detail.recName;
            }
            sb.append(seqNo).append(msf)
                    .append("0".equals(detail.sameBnk) ? "1" : "0").append(msf)//0:是浦发 1:否
                    .append("1".equals(detail.isPrivate) ? "1" : "0").append(msf)//0:对公 1:对私
                    .append(cardtype).append(msf)//0：对公帐号  1：卡 2：活期一本通 8：活期存折 9：内部帐/表外帐
                    .append(oppAct).append(msf)//对方账号
                    .append(oppActNm).append(msf)//对方户名
                    .append("").append(msf)//证件类型
                    .append("").append(msf)//证件号码
                    .append(cnapsCode).append(msf)//对手行号
                    .append(cnapsName).append(msf)//对手行名
                    .append(payBankNo).append(msf)//支付行号 32
                    .append(convertCurToBank(p_req.ownCur)).append(msf)//币种CNY
                    .append(detail.payAmount).append(msf)//金额
                    .append("").append(msf)//手机号
                    .append(detail.askNumber).append(msf)//企业流水号
                    .append("").append(msf)//集团企业分支编码,非集团企业不用填写
                    .append("").append(msf)//摘要
                    .append(detail.useType).append(msf)//备注
                    .append("").append(msf)//备注1
                    .append("").append(msf)//备注2
                    .append("");//备注3
            list.addChild((new XElement("detailedContent", sb.toString())));
            lists.addChild(list);
            seqNo++;
        }
        xmlWriter.writeXElement(tmpXElement);
        xmlWriter.writeEndDocument();//写入报文完成
        String[] tmpStrRet = sendToBank(xmlWriter.toXmlString(), tmpBnkHeader);//发送银行
        if (tmpStrRet[0].length() == 0) {
            StringBuilder tmpSbMsg = new StringBuilder();
            //解析银行返回
            XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
            if (tmpBkReader != null) {
                String returnCode = tmpBkReader.getFirstText("/packet/head/returnCode");
                String returnMsg = tmpBkReader.getFirstText("/packet/head/returnMsg");
                if (StringHelper.hasAnyChar(returnCode)) {
                    retAts.respCode = "0";
                    if (returnMsg == null || "".equals(returnMsg)) {
                        returnMsg = tmpBkReader.getFirstText("/packet/body/returnMsg");
                    }
                    if ("AAAAAAA".equals(returnCode)) {
                        retAts.transState = returnCode;
                        retAts.payInfoCode = returnCode;
                        retAts.respInfo = "提交成功";
                        retAts.reqSeqID = tmpBkReader.getFirstText("/packet/body/elecChequeNo");
                    } else {
                        retAts.transState = returnCode;
                        retAts.payInfoCode = returnCode;
                        retAts.respInfo = returnMsg;
                        retAts.reqSeqID = batchNo;
                    }
                } else {
                    retAts.respCode = "-1";
                    if (StringHelper.hasAnyChar(returnMsg)) {
                        retAts.respInfo = returnMsg;
                    } else {
                        retAts.respInfo = "returnCode节点为空";
                    }
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = tmpSbMsg.toString();
            }
        } else {
            retAts.respCode = "-1";
            retAts.respInfo = tmpStrRet[1];
        }
        retAts.writeRetToATS();
        return retAts;
    }

    private RetAtsQryBatPayRec qryBatPayRec(ReqQryBatPayRec p_req) throws Exception {
        //返回ATS的对象
        RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_req.reqHeader);
        String batchNo = p_req.reqBatchNO;
        String transtype = p_req.reqHeader.transType;
        try {
            SPDB01Header tmpBnkHeader = new SPDB01Header();
            tmpBnkHeader.transCode = "AQ53";
            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
            xmlWriter.autoFormat = false;
            xmlWriter.writeStartElement("body");
            xmlWriter.writeElementString("transMasterID", bankFront.protocolNo);
            xmlWriter.writeElementString("projectNumber", bankFront.corpNo);
            String costItemCode = "";
            if ("1998".equals(transtype)) {
                costItemCode = "batPay|" + p_req.ownAct;
            } else {
                costItemCode = "batRec|" + p_req.ownAct;
            }
            xmlWriter.writeElementString("costItemCode", costItemCodeMap(costItemCode));
            xmlWriter.writeElementString("elecChequeNo", batchNo);
            xmlWriter.writeElementString("handleSeqNo", "");
            Calendar tmpBGNDAT = Calendar.getInstance();
            tmpBGNDAT.setTime(p_req.getBgnDateTime());
            tmpBGNDAT.add(Calendar.DAY_OF_MONTH, -1);
            xmlWriter.writeElementString("beginDate", Format.Date8Format.format(tmpBGNDAT.getTime()));
            tmpBGNDAT.add(Calendar.DAY_OF_MONTH, 2);
            xmlWriter.writeElementString("endDate", Format.Date8Format.format(tmpBGNDAT.getTime()));
            xmlWriter.writeElementString("queryNumber", "1");
            xmlWriter.writeElementString("beginNumber", "1");
            xmlWriter.writeEndDocument();
            String[] tmpRetBkStr = sendToBank(xmlWriter.toXmlString(), tmpBnkHeader);
            if (tmpRetBkStr[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetBkStr[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String returnCode = tmpBkReader.getFirstText("/packet/head/returnCode");
                    String returnMsg = tmpBkReader.getFirstText("/packet/head/returnMsg");
                    if (StringHelper.isNullOrEmpty(returnMsg)) {
                        returnMsg = tmpBkReader.getFirstText("/packet/body/returnMsg");
                    }
                    if (returnCode != null && "AAAAAAA".equals(returnCode)) {
                        retAts.respCode = "0";

                        String bkTotalCount = tmpBkReader.getFirstText("/packet/body/recordNumber");
                        int totalCount = -1;
                        if (StringHelper.hasAnyChar(bkTotalCount)) {
                            totalCount = Integer.parseInt(bkTotalCount);
                        }
                        if (tmpBkReader.read("/packet/body/lists/list")) {
                            String elecChequeNo = tmpBkReader.readedXElement.getSingleText("elecChequeNo");
                            if (batchNo.equals(elecChequeNo)) {
                                retAts.reqSeqID = elecChequeNo;
                                //0:成功；1:失败；2:处理中； 3:异常（需管理端处理）
                                String batchHandleStatus = tmpBkReader.readedXElement.getSingleText("batchHandleStatus");
                                if ("0".equals(batchHandleStatus)) {
                                    tmpBnkHeader.transCode = "AQ54";
                                    XmlTextWriter xmlWriter2 = new XmlTextWriter();//发银行报文的XML对象
                                    xmlWriter2.autoFormat = false;
                                    xmlWriter2.writeStartElement("body");
                                    xmlWriter2.writeElementString("transMasterID", bankFront.protocolNo);
                                    xmlWriter2.writeElementString("projectNumber", bankFront.corpNo);
                                    xmlWriter2.writeElementString("costItemCode", costItemCodeMap(costItemCode));
                                    xmlWriter2.writeElementString("transDate", Format.Date8Format.format(p_req.getBgnDateTime()));
                                    xmlWriter2.writeElementString("electronNumber", batchNo);
                                    xmlWriter2.writeElementString("handleSeqNo", "");
                                    xmlWriter2.writeEndDocument();
                                    tmpRetBkStr = sendToBank(xmlWriter2.toXmlString(), tmpBnkHeader);
                                    if (tmpRetBkStr[0].length() == 0) {
                                        tmpBkReader = loadBankRespXmlReader(tmpRetBkStr[1], tmpSbMsg);
                                        if (tmpBkReader != null) {
                                            returnCode = tmpBkReader.getFirstText("/packet/head/returnCode");
                                            returnMsg = tmpBkReader.getFirstText("/packet/head/returnMsg");
                                            if (StringHelper.isNullOrEmpty(returnMsg)) {
                                                returnMsg = tmpBkReader.getFirstText("/packet/body/returnMsg");
                                            }
                                            if (returnCode != null && "AAAAAAA".equals(returnCode)) {
                                                elecChequeNo = tmpBkReader.getFirstText("/packet/body/electronNumber");
                                                retAts.respCode = "0";
                                                retAts.reqSeqID = elecChequeNo;
                                                while (tmpBkReader.read("/packet/body/lists/list")) {
                                                    String detailRes = tmpBkReader.readedXElement.getSingleText("detailedContent");
                                                    if (detailRes != null && !"".equals(detailRes)) {
                                                        //0明细序号|1是否浦发账户|2收付款人对公对私标志|3银行卡卡类型|4账号|5账户名|6证件类型|7证件号码|8对手行行号|9对手行行名|10
                                                        // 支付行号|11币种|12金额|13手机号|14企业流水号|15备用信息|16企业分支机构|17摘要|18备注|19备用1|20备用2|21备用3|22状态|23错误信息
                                                        RetAtsBatPayRecDetail retDetail = new RetAtsBatPayRecDetail();
                                                        String[] res = detailRes.split("\\|");
                                                        String oppAct = res[4];
                                                        String oppActNm = res[5];
                                                        if ("1998".equals(transtype)) {
                                                            retDetail.recAct = oppAct;
                                                            retDetail.recName = oppActNm;
                                                        } else {
                                                            retDetail.payAct = oppAct;
                                                            retDetail.payName = oppActNm;
                                                        }
                                                        retDetail.postScript = res[14];
                                                        retDetail.payAmount = res[12];
                                                        retDetail.usage = res[17] + "+" + res[18];
                                                        retDetail.result = returnCode + "+" + res[22];
                                                        retDetail.payInfoCode = res[23];
                                                        retDetail.memo = res[23];
                                                        retAts.writeRetDetail(retDetail);
                                                    }
                                                }
                                            } else {
                                                retAts.respCode = "0";
                                                retAts.transState = returnCode;
                                                retAts.respInfo = returnMsg;
                                                retAts.respCode = returnCode;
                                                retAts.reqSeqID = p_req.reqBatchNO;
                                            }
                                        }
                                    }
                                } else if ("1".equals(batchHandleStatus)) {
                                    retAts.respInfo = "批处理失败";
                                    retAts.reqSeqID = elecChequeNo;
                                    retAts.transState = returnCode + "+" + batchHandleStatus;
                                    retAts.respCode = retAts.transState;
                                    return retAts;
                                } else if ("2".equals(batchHandleStatus)) {
                                    retAts.respCode = "0";
                                    retAts.respInfo = "银行未处理完成";
                                    retAts.transState = returnCode + "+" + batchHandleStatus;
                                    retAts.payInfoCode = returnCode + "+" + batchHandleStatus;
                                } else if ("3".equals(batchHandleStatus)) {
                                    retAts.respCode = "-1";
                                    retAts.respInfo = "异常（需管理端处理）";
                                }
                            }
                        } else if (totalCount == 0) {
                            retAts.respCode = "-1";
                            retAts.respInfo = "查询没有记录";
                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = "recordNumber节点为空";
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = returnMsg;
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpSbMsg.toString();
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = tmpRetBkStr[1];
            }
        } catch (Exception e) {
            retAts.respCode = "-1";
            retAts.respInfo = e.getMessage();
            e.printStackTrace();
        }

        retAts.writeAfterDetail();
        return retAts;
    }
}